import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';
import * as THREE from 'three';
import {Clazz} from "./Clazz";

class Robot extends Clazz {
    constructor() {
        super();
        const _this = this;
        this.position = new THREE.Vector3(0, 200, 0);
        this.clock = new THREE.Clock();
        this.size = new THREE.Vector3(20, 40, 20);
        this.ready = false;
        _this.quaternion = new THREE.Vector3();
        const loader = new GLTFLoader();
        loader.load('../js/components/images/robot/RobotExpressive.glb', function (gltf) {
            const model = gltf.scene;
            model.scale.set(8, 8, 8);
            _this.model = model;
            _this.createOutline();
            _this.ready = true;
            _this.outline.scale.set(20, 40, 20);
            scene.add(_this.outline)
            scene.add(model);
            _this.rotation = model.rotation;
            _this.quaternion = model.quaternion;
            _this.createGUI(model, gltf.animations);
        }, undefined, function (e) {
            console.error(e);
        });
    }


    createGUI(model, animations) {

        const states = ['Idle', 'Walking', 'Running', 'Dance', 'Death', 'Sitting', 'Standing'];
        const emotes = ['Jump', 'Yes', 'No', 'Wave', 'Punch', 'ThumbsUp'];
        const clip = animations[10];
        this.mixer = new THREE.AnimationMixer(model);
        const action = this.mixer.clipAction(clip);
        console.log(animations);
        action.play();
        //this.gui = new GUI();

        /*this.mixer = new THREE.AnimationMixer(model);

        this.actions = {};
        const _this = this;
        for (let i = 0; i < animations.length; i++) {

            const clip = animations[i];
            const action = this.mixer.clipAction(clip);
            this.actions[clip.name] = action;

            if (emotes.indexOf(clip.name) >= 0 || states.indexOf(clip.name) >= 4) {

                action.clampWhenFinished = true;
                action.loop = THREE.LoopOnce;

            }

        }

        // states

        const statesFolder = this.gui.addFolder('States');

        const clipCtrl = statesFolder.add(_this.api, 'state').options(states);

        clipCtrl.onChange(function () {

            _this.fadeToAction(_this.api.state, 0.5);

        });

        statesFolder.open();

        // emotes

        const emoteFolder = this.gui.addFolder('Emotes');

        function createEmoteCallback(name) {

            _this.api[name] = function () {

                _this.fadeToAction(name, 0.2);

                _this.mixer.addEventListener('finished', restoreState);

            };

            emoteFolder.add(_this.api, name);

        }

        function restoreState() {

            this.mixer.removeEventListener('finished', restoreState);

            this.fadeToAction(this.api.state, 0.2);

        }

        for (let i = 0; i < emotes.length; i++) {

            createEmoteCallback(emotes[i]);

        }

        emoteFolder.open();

        // expressions

        this.face = model.getObjectByName('Head_4');

        const expressions = Object.keys(_this.face.morphTargetDictionary);
        const expressionFolder = _this.gui.addFolder('Expressions');

        for (let i = 0; i < expressions.length; i++) {

            expressionFolder.add(this.face.morphTargetInfluences, i, 0, 1, 0.01).name(expressions[i]);

        }*/

        /*this.activeAction = this.actions['Walking'];
        this.activeAction.play();*/

        /*expressionFolder.open();*/

    }

    fadeToAction(name, duration) {

        this.previousAction = this.activeAction;
        this.activeAction = this.actions[name];

        if (this.previousAction !== this.activeAction) {

            this.previousAction.fadeOut(duration);

        }

        this.activeAction
            .reset()
            .setEffectiveTimeScale(1)
            .setEffectiveWeight(1)
            .fadeIn(duration)
            .play();

    }

    update() {
        super.update();
        if (this.ready) {
            this.outline.position.copy(this.position);
            this.model.position.set(this.position.x,this.position.y-20,this.position.z);
        }

        const dt = this.clock.getDelta();
        //this.position.x+=dt*10;
        if (this.mixer) this.mixer.update(dt);
    }

    getSize() {
        return this.size;
    }


}

export {Robot}